<template>
  <a-upload
    v-model:file-list="fileList"
    :before-upload="beforeUpload"
    list-type="picture-card"
    @remove="handleRemove"
    @preview="handlePreview"
  >
    <div>
      <plus-outlined />
      <div style="margin-top: 8px">上传</div>
    </div>
  </a-upload>
</template>

<script setup>
import { getCurrentInstance, onMounted, ref, watch } from "vue";
import { PlusOutlined } from "@ant-design/icons-vue";
import _ from "lodash";

const { proxy } = getCurrentInstance();
const props = defineProps({ files: Array });
const emit = defineEmits(["update:imgs"]);

const fileList = ref([]);
// 首次挂载
onMounted(() => {
  fileList.value = (props.imgs || []).map((o, i) => {
    // 要求file为URL
    if (_.isString(o)) {
      const name = o.substring(o.lastIndexOf("/") + 1, o.length);
      return { uid: i, url: o, name };
    }
  });
});

const handleRemove = (file) => {
  const index = fileList.value.indexOf(file);
  const newFileList = fileList.value.slice();
  newFileList.splice(index, 1);
  fileList.value = newFileList;
};

const beforeUpload = (file) => {
  const imgTypes = ["image/jpeg", "image/png", "image/jpg"];
  const isJPG = _.includes(imgTypes, file.type);

  if (!isJPG) {
    proxy.$message.error("仅允许上传的文件类型JPG,JPEG,PNG!");
  }
  const isLt20M = file.size / 1024 / 1024 < 20;
  if (!isLt20M) {
    proxy.$message.error("文件大小不能超过20MB!");
  }
  if (isJPG && isLt20M) {
    fileList.value = [...fileList.value, file];
  }
  return false;
};

function getBase64(file) {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.readAsDataURL(file);
    reader.onload = () => resolve(reader.result);
    reader.onerror = (error) => reject(error);
  });
}

const handlePreview = async (file) => {
  if (!file.url && !file.preview) {
    file.preview = await getBase64(file.originFileObj);
  }
  proxy.$viewerApi({
    options: {
      toolbar: false,
      navbar: false,
      title: false,
    },
    images: [file.url || file.preview],
  });
};

watch(
  () => fileList.value,
  (v) => {
    emit("update:imgs", v);
  }
);
</script>

<style lang="less" scoped></style>
